home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 April / EnigmA AMIGA RUN 17 (1997)(G.R. Edizioni)(IT)[!][issue 1997-04][EAR-CD].iso / EARCD / comm / bbs / citsrc6K05.lha / route.c < prev    next >
C/C++ Source or Header  |  1996-08-31  |  23KB  |  892 lines

  1. /*
  2. *       Route.C
  3. *
  4. * Some of the C86Net routemail code.
  5. */
  6. #include "ctdl.h"
  7. /*
  8. *       history
  9. *
  10. * 89Feb?? HAW  Created.
  11. */
  12. /*
  13. *                              contents
  14. *
  15. * netRouteMail()    Incoming route mail
  16. * MakeRouted()    ST route mail => C86Net
  17. */
  18. int    RouteSlot;
  19. char   RouteMailForHere;
  20. int    RouteToDirect = ERROR;
  21. static int  RWorkBuf[7];
  22. char RCount, SCount;
  23. extern int       TransProtocol;
  24. extern char      TrError;
  25. extern PROTO_TABLE Table[];
  26. extern CONFIG    cfg;
  27. extern NetBuffer netBuf, netTemp;
  28. extern NetTable  *netTab;
  29. extern FILE      *upfd, *netMisc, *netLog;
  30. extern int       thisNet;
  31. extern MessageBuffer   msgBuf;
  32. extern logBuffer logBuf;
  33. extern long ByteCount, EncCount;
  34. extern char logNetResults;
  35. extern char netDebug;
  36.  
  37. #define BAD_ROUTE "%s did not recognize %s (%s) for routed mail (%s)."
  38. #define NodeDisabled(x) (!(netTab[x].ntMemberNets & ALL_NETS))
  39. static char ParseSTRoute(char *str, char **TargetSystem, char **Domain,
  40. char **UserName);
  41. static void prStStyle(int mode, char *Name, int  (*M)(int c), char *Domain);
  42. extern int (*NetCharSource)(void);
  43. /**** These functions handle incoming route mail. ****/
  44. /*
  45. * netRouteMail() should be called in the Net Receive routines, in the big
  46. * case statement.
  47. */
  48. int RMcount = 0;                /* Incoming RoutMail count for us       */
  49. /*
  50. * netRouteMail()
  51. *
  52. * The caller has asked us to route Mail somewhere.  We determine if we want
  53. * to accept the mail or not, and if we do then we do, in fact, receive it.
  54. */
  55. void netRouteMail(struct cmd_data *cmds)
  56.   {
  57.   DOMAIN_FILE fn;
  58.   label       temp;
  59.   int   val;
  60.   char  MailForUs = FALSE, bad, dup;
  61.   extern char *APPEND_ANY, PosId;
  62.   label       Name, Id;
  63.   /*
  64.   * Do we do net routing?  At all?  From this node?  To the indicated
  65.   * node?  Even if we don't do routing per se, we should accept routed
  66.   * mail intended for this system, which is handled by RouteHere().
  67.   * Also, we do not route to disabled nodes.
  68.   */
  69.   if (cfg.BoolFlags.debug)
  70.     {
  71.     short i;
  72.     splitF(netLog, "netRouteMail(%08.8x)\n",cmds);
  73.     splitF(netLog, " struct cmd ");
  74.     splitF(netLog, "   {\n");
  75.     splitF(netLog, "   command=%x\n",cmds->command);
  76.     for(i=0;i<4;i++) splitF(netLog, "   fields[%d]:%s\n",i,cmds->fields[i]);
  77.     splitF(netLog, "   }\n");
  78.     splitF(netLog,"netBuf.nbflags.RouteFor(%x) RouteMail(%x)\n",
  79.     (int)cfg.BoolFlags.RouteMail,(int)netBuf.nbflags.RouteFor);
  80.     };
  81.   bad = (!PosId ||
  82.   (!(MailForUs = RouteHere(cmds->fields[0], cmds->fields[1],
  83.   cmds->fields[2]))) &&
  84.   (!cfg.BoolFlags.RouteMail || !netBuf.nbflags.RouteFor));
  85.   if (!bad && !MailForUs)
  86.     {
  87.     if (!FindTheNode(cmds->fields[0], ""))
  88.       {
  89.       if (strLen(cmds->fields[2]) != 0)
  90.         {
  91.         bad = ((val=DomainMailFileName(fn, cmds->fields[2],
  92.         cmds->fields[0], cmds->fields[1])) == REFUSE);
  93.  
  94.         }
  95.       else val = (MailForUs) ? OURS : LOCALROUTE;
  96.       if (!bad && val == LOCALROUTE)
  97.         {
  98.         bad = (!AcceptRoute(cmds->fields[0],"") ||
  99.         NodeDisabled(RouteSlot));
  100.  
  101.         }
  102.       /* trying to route mail without domain we don't know about? */
  103.       if (bad && strLen(cmds->fields[2]) == 0)
  104.         {
  105.         if (SystemInSecondary(cmds->fields[1], cmds->fields[2], &dup))
  106.         if (!dup)
  107.           {
  108.           bad = FALSE;
  109.           val=DomainMailFileName(fn, cmds->fields[2],
  110.           cmds->fields[0], cmds->fields[1]);
  111.  
  112.           }
  113.  
  114.         }
  115.  
  116.       }
  117.     else val = LOCALROUTE;
  118.  
  119.     }
  120.   else if (MailForUs) val = OURS;
  121.   if (bad)
  122.     {
  123.     if( logNetResults )
  124.     splitF(netLog, "Rejecting %s (%s)\n", cmds->fields[1], cmds->fields[0]);
  125.     reply(BAD, "not routing to this node for you");
  126.     return;
  127.  
  128.     }
  129.   if (val == LOCALROUTE)
  130.     {
  131.     strCpy(Name, netTemp.netName);
  132.     strCpy(Id, netTemp.netId);
  133.     FindRouteSlot();
  134.  
  135.     }
  136.   if (!MailForUs)
  137.   MailForUs = val == OURS;
  138.   if (MailForUs)
  139.     {
  140.     sPrintf(temp, "rmail.%d", RMcount++);
  141.     makeSysName(fn, temp, &cfg.netArea);
  142.  
  143.     }
  144.   else if (val == LOCALROUTE)
  145.     {
  146.     /* Ugly ugly kludge until we figure out how nbHiRouteInd is wrong */
  147.     if (netTemp.nbHiRouteInd < 0) netTemp.nbHiRouteInd = 0;
  148.     sPrintf(temp, "R%d.%d", RouteSlot, netTemp.nbHiRouteInd++);
  149.     makeSysName(fn, temp, &cfg.netArea);
  150.  
  151.     }
  152.   else
  153.     {
  154.     strCpy(Name, cmds->fields[1]);
  155.     strCpy(Id, cmds->fields[0]);
  156.  
  157.     }
  158.   if ((upfd = safeopen(fn, APPEND_ANY)) == NULL)
  159.     {
  160.     reply(BAD, "internal error");
  161.     splitF(netLog, "internal error, couldn't open %s\n", fn);
  162.     return;
  163.  
  164.     }
  165.   if (!MailForUs)
  166.     {
  167.     strCpy(Name, UseNetAlias(Name, TRUE));
  168.     fprintf(upfd, "%-20s", Id);
  169.     putc(0, upfd);
  170.     fprintf(upfd, "%-20s", Name);
  171.     putc(0, upfd);
  172.  
  173.     }
  174.   if( logNetResults )
  175.     splitF(netLog, "Route mail for %s/%s/%s.\n", cmds->fields[1],Id,Name);
  176.   if (!MailForUs)
  177.   StartEncode(putFLChar);
  178.   if (ITL_StartRecMsgs(fn, TRUE, FALSE, (!MailForUs) ? Encode : NULL)
  179.   != ITL_SUCCESS)
  180.     {
  181.     switch (val)
  182.       {
  183.       case LOCALROUTE:
  184.       netTemp.nbHiRouteInd--; break;
  185.       case DOMAINFILE:
  186.       DomainFileAddResult(cmds->fields[2], "", "", DOMAIN_FAILURE); break;
  187.  
  188.       }
  189.     MailForUs = FALSE;
  190.     splitF(netLog, "Problem receiving routemail\n");
  191.  
  192.     }
  193.   else
  194.     {
  195.     /*
  196.     * Now we note the fact that we have received routed mail.
  197.     */
  198.     switch (val)
  199.       {
  200.       case LOCALROUTE:
  201.       netTemp.nbflags.HasRouted = TRUE;
  202.       putNet(RouteSlot, &netTemp);
  203.       break;
  204.       case DOMAINFILE:
  205.       DomainFileAddResult(cmds->fields[2], Name, cmds->fields[0],
  206.       DOMAIN_SUCCESS); break;
  207.  
  208.       }
  209.  
  210.     }
  211.   if (MailForUs)
  212.   RouteMailForHere = TRUE;
  213.  
  214.   }
  215. /*
  216. * AcceptRoute()
  217. *
  218. * Will we route to the given node?
  219. */
  220. char AcceptRoute(char *id, char *name)
  221.   {
  222.   if (cfg.BoolFlags.debug)
  223.     {
  224.     splitF(netLog, "AcceptRoute(%s,%s)=%s\n",id,name
  225.     , (( netTemp.nbflags.RouteTo) ? "TRUE ":"FALSE"));
  226.     };
  227.   if (!FindTheNode(id, name)) return FALSE;
  228.   return (char)netTemp.nbflags.RouteTo;
  229.  
  230.   }
  231. /*
  232. * FindTheNode()
  233. *
  234. * This function will see if the node exists.  It will leave the index in
  235. * RouteSlot and return TRUE if found, FALSE otherwise.  This does not try
  236. * to utilize the secondary node lists.
  237. */
  238. char FindTheNode(char *id, char *name)
  239.   {
  240.   if (cfg.BoolFlags.debug)
  241.     {
  242.     splitF(netLog, "FindTheNode(%s,%s)\n",id,name);
  243.     };
  244.   if ((RouteSlot = searchNet(id, &netTemp)) != ERROR) return TRUE;
  245.   if (strLen(name) == 0) return FALSE;
  246.   if ((RouteSlot = searchNameNet(name, &netTemp)) == ERROR &&
  247.   (RouteSlot = searchNameNet(UseNetAlias(name,FALSE), &netTemp))==ERROR)
  248.   return FALSE;
  249.   return TRUE;
  250.  
  251.   }
  252. /*
  253. * FindRouteSlot()
  254. *
  255. * This function will find the slot of the routing node.  If found, netTemp
  256. * will contain the new slot, as will RouteSlot, and RouteSlot will be
  257. * returned.
  258. */
  259. int FindRouteSlot()
  260.   {
  261.   /*
  262.   * first check to see if we're the direct (final) link, either
  263.   * expressly or because the route is outdated.
  264.   */
  265.   if (!DirectRoute(&netTemp))            /* expressly?   */
  266.   getNet((RouteSlot = netTemp.nbRoute), &netTemp);
  267.   return RouteSlot;
  268.  
  269.   }
  270. /*
  271. * DirectRoute()
  272. *
  273. * This function will discover if we directly or indirectly talk to this node.
  274. */
  275. char DirectRoute(NetBuffer *n)
  276.   {
  277.   return (char) (n->nbRoute == -1 ||             /* expressly?   */
  278.   n->nbRoute >= cfg.netSize ||  /* outdated? */
  279.   !netTab[n->nbRoute].ntflags.in_use ||    /* outdated?    */
  280.   netTab[n->nbRoute].ntGen != n->nbRouteGen);/* outdated?*/
  281.  
  282.   }
  283. /**** These functions handle outgoing route mail. ****/
  284. /*
  285. * RouteOut()
  286. *
  287. * This is the manager of sending outgoing route mail to the current node.  It
  288. * must handle error conditions.
  289. */
  290. void RouteOut()
  291.   {
  292.   char            abort = FALSE, failed = FALSE;
  293.   int             rover, result;
  294.   label           temp, Tid, Tname, ThisId;
  295.   SYS_FILE        fn;
  296.   extern char     *READ_ANY, OverRides;
  297.   extern AN_UNSIGNED RecBuf[];
  298.   if (netBuf.nbflags.Stadel)
  299.     {
  300.     RouteToDirect = 0;
  301.     return;
  302.  
  303.     }
  304.   normId(netBuf.netId, ThisId);
  305.   for (rover = 0; rover <= netBuf.nbHiRouteInd && !abort; rover++)
  306.     {
  307.     sPrintf(temp, "R%d.%d", thisNet, rover);
  308.     makeSysName(fn, temp, &cfg.netArea);
  309.     if ((result = SendRouteMail(fn, "", Tid, Tname, FALSE)) == GOOD_SEND)
  310.     unlink(fn);
  311.     else if (result == REFUSED_ROUTE)
  312.       {
  313.       /*
  314.       * Bad return.  Could be
  315.       *   a) system is not compatible at this level, or
  316.       *   b) system doesn't know about target
  317.       */
  318.       if (strCmpU(ThisId, Tid) == SAMESTRING)
  319.         {
  320.         if( netDebug && logNetResults )
  321.           splitF(netLog, "Rerouting to use normal mail.\n");
  322.         if (RouteToDirect == -1)
  323.           {
  324.           RouteToDirect = rover;
  325.  
  326.           }
  327.  
  328.         }
  329.       else
  330.         {
  331.         sPrintf(msgBuf.mbtext, BAD_ROUTE, netBuf.netName,
  332.         Tname, Tid, RecBuf + 1);
  333.         netResult(msgBuf.mbtext);
  334.         failed = TRUE;
  335.  
  336.         }
  337.  
  338.       }
  339.     else failed = TRUE; /* something failed, dunno what */
  340.  
  341.     }
  342.   if (!abort && !failed)
  343.     {
  344.     netBuf.nbflags.HasRouted = FALSE;
  345.     netBuf.nbHiRouteInd      = 0;
  346.  
  347.     }
  348.  
  349.   }
  350. /*
  351. * SendRouteMail()
  352. *
  353. * This function will send route mail.
  354. */
  355. char SendRouteMail(char *filename, char *domainname, char *Tid, char *Tname,
  356. char LocalCheck)
  357.   {
  358.   struct cmd_data cmds;
  359.   char work[(2 * NAMESIZE) + 10];
  360.   label ThisId;
  361.   normId(netBuf.netId, ThisId);
  362.   if ((netMisc = safeopen(filename, READ_ANY)) != NULL)
  363.     {
  364.     getMsgStr(getNetChar, cmds.fields[0], NAMESIZE);
  365.     getMsgStr(getNetChar, cmds.fields[1], NAMESIZE);
  366.     if (!normId(cmds.fields[0], Tid) || strLen(Tid) == 0)
  367.     strCpy(cmds.fields[0], "  ");
  368.     else
  369.     strCpy(cmds.fields[0], Tid);
  370.     if (LocalCheck)
  371.     if (!netBuf.nbflags.Stadel && strCmpU(Tid,ThisId) != SAMESTRING)
  372.       {
  373.       fclose(netMisc);
  374.       return REFUSED_ROUTE; /* actually, just a lie */
  375.  
  376.       }
  377.     NormStr(cmds.fields[1]);
  378.     strCpy(Tname, cmds.fields[1]);    /* reporting purposes */
  379.     strCpy(cmds.fields[2], domainname); /* just for luck        */
  380.     cmds.command = ROUTE_MAIL;
  381.     if( logNetResults )
  382.       {
  383.       if (strLen(domainname) != 0 )
  384.         splitF(netLog, "Routing mail to %s _ %s/%s/%s\n", cmds.fields[1],
  385.         domainname,
  386.         (Tid != NULL) ? Tid : "NULL", (Tname != NULL) ? Tname : "NULL" );
  387.       else
  388.         splitF(netLog, "Routing mail to %s/%s/%s\n", cmds.fields[1],
  389.         (Tid != NULL) ? Tid : "NULL", (Tname != NULL) ? Tname : "NULL" );
  390.       };
  391.     if (LocalCheck || sendNetCommand(&cmds, "Route Mail"))
  392.       {
  393.       if (LocalCheck || ITL_SendMessages())
  394.         {
  395.         StartDecode(ReadRoutedDest);
  396.         RCount = SCount = 0;
  397.         NetCharSource = ReadRouted;
  398.         sPrintf(work,
  399.         (strLen(domainname) != 0) ? "%s _ %s" : "%s%s",
  400.         cmds.fields[1], domainname);
  401.         while (getMessage(ReadRouted, TRUE, FALSE, TRUE))
  402.         if (netBuf.nbflags.Stadel)
  403.         prStStyle(1, Tname, sendITLchar, domainname);
  404.         else
  405.         prNetStyle(1, sendITLchar, TRUE, work);
  406.         NetCharSource = getNetChar;
  407.         fclose(netMisc);
  408.         if (!LocalCheck) ITL_StopSendMessages();
  409.         if (cfg.BoolFlags.debug)
  410.         splitF(netLog, "Encoded %ld bytes, sent %ld bytes.\n", EncCount, ByteCount);
  411.         if (TrError == TRAN_SUCCESS)
  412.         return GOOD_SEND;
  413.         else
  414.         return UNKNOWN_ERROR;
  415.  
  416.         }
  417.  
  418.       }
  419.     else
  420.       {
  421.       if( logNetResults && netDebug )splitF(netLog, "RouteMail rejection!\n");
  422.       fclose(netMisc);
  423.       return REFUSED_ROUTE;
  424.  
  425.       }
  426.  
  427.     }
  428.   return NO_SUCH_FILE;
  429.  
  430.   }
  431. /*
  432. * AdjustRoute()
  433. *
  434. * This function adjusts the routed files names.  Basically, it finds "holes"
  435. * in the sequence of numerical filenames and adjusts names to fill those
  436. * holes.
  437. */
  438. void AdjustRoute()
  439.   {
  440.   int      rover, next;
  441.   label    temp;
  442.   SYS_FILE fn, fn2;
  443.   rover = 0;
  444.   while (rover < netBuf.nbHiRouteInd)
  445.     {
  446.     sPrintf(temp, "R%d.%d", thisNet, rover);
  447.     makeSysName(fn, temp, &cfg.netArea);
  448.     if (access(fn, 0) != 0)
  449.       {
  450.       next = rover + 1;
  451.       do
  452.         {
  453.         sPrintf(temp, "R%d.%d", thisNet, next++);
  454.         makeSysName(fn2, temp, &cfg.netArea);
  455.  
  456.         }
  457.       while (access(fn2, 0) != 0 && next <= netBuf.nbHiRouteInd);
  458.       if (access(fn2, 0) != 0)
  459.         {
  460.         if (rover == 0)
  461.           {
  462.           netBuf.nbflags.HasRouted = FALSE;
  463.           netBuf.nbHiRouteInd = 0;
  464.  
  465.           }
  466.         else
  467.         netBuf.nbHiRouteInd = rover - 1;
  468.         break;
  469.  
  470.         }
  471.       else
  472.         {
  473.         rename(fn2, fn);
  474.         rover++;
  475.  
  476.         }
  477.  
  478.       }
  479.     rover++;
  480.  
  481.     }
  482.   /* I think* this is right. */
  483.   if (rover == 0)
  484.     {
  485.     netBuf.nbflags.HasRouted = FALSE;
  486.     netBuf.nbHiRouteInd = 0;
  487.  
  488.     }
  489.  
  490.   }
  491. /*
  492. * SendRoutedAsLocal()
  493. *
  494. * This function will reroute route mail to use local mail.
  495. */
  496. int SendRoutedAsLocal()
  497.   {
  498.   label ThisId, Tid, Name, temp;
  499.   SYS_FILE fn;
  500.   char finished = FALSE;
  501.   int  toReturn = 0, result;
  502.   extern char OverRides;
  503.   if (RouteToDirect == -1 && !netBuf.nbflags.Stadel) return 0;
  504.   normId(netBuf.netId, ThisId);
  505.   do
  506.     {
  507.     sPrintf(temp, "R%d.%d", thisNet, RouteToDirect++);
  508.     makeSysName(fn, temp, &cfg.netArea);
  509.     if ((result = SendRouteMail(fn, "", Tid, Name, TRUE)) == GOOD_SEND)
  510.       {
  511.       unlink(fn);
  512.       toReturn++;
  513.  
  514.       }
  515.     else if (result == NO_SUCH_FILE)
  516.     finished = TRUE;
  517.  
  518.     }
  519.   while (!finished);
  520.   return toReturn;
  521.  
  522.   }
  523. /*
  524. * ReadRoutedDest()
  525. *
  526. * This work function will help read encrypted (style 1) data.
  527. */
  528. int ReadRoutedDest(int c)
  529.   {
  530.   RWorkBuf[RCount++] = c;
  531.   return TRUE;
  532.  
  533.   }
  534. /*
  535. * ReadRouted()
  536. *
  537. * This function will read a routed char for getMessage().
  538. */
  539. int ReadRouted()
  540.   {
  541.   int c;
  542.   if (RCount != SCount)
  543.   return RWorkBuf[SCount++];
  544.   RCount = SCount = 0;
  545.   while (SCount == RCount && (c = fgetc(netMisc)) != EOF)
  546.   Decode(c);
  547.   if (RCount != SCount)
  548.   return RWorkBuf[SCount++];
  549.   if (c == EOF) StopDecode();
  550.   if (RCount != SCount)
  551.   return RWorkBuf[SCount++];
  552.   return -1;
  553.  
  554.   }
  555. /*
  556. * prStStyle()
  557. *
  558. * This is used to handle problems inherent in STadel mail routing.
  559. */
  560. static void prStStyle(int mode, char *Name, int (*M)(int c), char *Domain)
  561.   {
  562.   char work[4 * NAMESIZE];
  563.   extern SListBase MailForward;
  564.   ForwardMail *address;
  565.   if (strCmpU(netBuf.netName, Name) != SAMESTRING)
  566.     {
  567.     if (!msgBuf.mbaddr[0])
  568.       {
  569.       if ((address = SearchList(&MailForward, msgBuf.mbto)) != NULL)
  570.       strCpy(msgBuf.mbto, address->Alias);
  571.  
  572.       }
  573.     if (strLen(Domain) != 0)
  574.       {
  575.       sPrintf(work, "%s.%s!%s", Name, Domain, msgBuf.mbto);
  576.       strCpy(msgBuf.mbto, work);
  577.  
  578.       }
  579.     else
  580.       {
  581.       sPrintf(work, "%s!%s", netBuf.netName, Name);
  582.       NormStr(work);  /* shave off trailing blanks... */
  583.       sPrintf(lbyte(work), "!%s", msgBuf.mbto);
  584.       strCpy(msgBuf.mbto, work);
  585.  
  586.       }
  587.  
  588.     }
  589.   if (strLen(msgBuf.mbdomain) != 0 && strLen(msgBuf.mboname) != 0)
  590.     {
  591.     sPrintf(work, "%s.%s!%s", msgBuf.mboname, msgBuf.mbdomain,
  592.     msgBuf.mbauth);
  593.     strCpy(msgBuf.mbauth, work);
  594.  
  595.     }
  596.   prNetStyle(mode, M, TRUE, Name);
  597.  
  598.   }
  599. /*
  600. * MakeRouted()
  601. *
  602. * This function transforms an ST route mail message into C86Net.
  603. *
  604. * Format: <system>![<system>!...]<username> ... I hope!
  605. *
  606. * There should also be allowances for using domain addresses.
  607. */
  608. void MakeRouted()
  609.   {
  610.   char  dup, *UserName, *TargetSystem, *Domain, work[(2 * NAMESIZE) + 6];
  611.   label TheDomain, System;
  612.   int   Slot, val = ERROR;
  613.   /*
  614.   * We parse the author field (which is the route back to the
  615.   * author, form [<system>!...]<home system>!<username>.  TargetSystem
  616.   * should have the name of the home system, UserName is obvious.  If
  617.   * TargetSystem contains a '.', then the address is domain-defined.
  618.   */
  619.   printf("MakeRouted\n");
  620.   if (ParseSTRoute(msgBuf.mbauth, &TargetSystem, &Domain, &UserName))
  621.     {
  622.     strCpy(msgBuf.mboname, TargetSystem);
  623.     msgBuf.mborig[0] = 0;
  624.     /*
  625.     * Is this domain mail?  If so, just set the domain stuff up
  626.     * correctly and don't worry whether we know this guy personally.
  627.     */
  628.     if (Domain != NULL)
  629.       {
  630.       strCpy(msgBuf.mbdomain, Domain);
  631.       strCpy(msgBuf.mboname, TargetSystem);
  632.  
  633.       }
  634.     else
  635.       {
  636.       /*
  637.       * So now we find out if we know the name.  If we do, netTemp will
  638.       * contain the appropriate net data.
  639.       */
  640.       if (IdStName(msgBuf.mboname) != ERROR)
  641.       strCpy(msgBuf.mborig, netTemp.netId);
  642.       strCpy(msgBuf.mbauth, UserName);
  643.  
  644.       }
  645.  
  646.     }
  647.   /*
  648.   * Now we parse the To field, which is potentially in the same format
  649.   * as the Author field, above.  TargetSystem is the final target,
  650.   * User name is the recipient.  If, for some reason, no target system
  651.   * is specified, we assume we are the target.
  652.   */
  653.   if (!ParseSTRoute(msgBuf.mbto, &TargetSystem, &Domain, &UserName))
  654.     {
  655.     TargetSystem = cfg.nodeName + cfg.codeBuf;
  656.     UserName = msgBuf.mbto;
  657.  
  658.     }
  659.   if( logNetResults )
  660.   if (Domain == NULL)
  661.   splitF(netLog, "Routing mail to %s.\n", TargetSystem);
  662.   else
  663.   splitF(netLog, "Routing mail to %s _ %s.\n", TargetSystem, Domain);
  664.   /* If we are the target, just deliver the damn message and get out. */
  665.   if (RouteHere("", TargetSystem, Domain))
  666.     {
  667.     strCpy(msgBuf.mbto, UserName);
  668.     putMessage(&logBuf);
  669.     return;
  670.  
  671.     }
  672.   /*
  673.   * OK, so the Mail is not for our system.  Find out whom and put in
  674.   * routing.
  675.   */
  676.   /*
  677.   * If we can't figure out the target system, dump it and die.
  678.   */
  679.   if ((Slot = IdStName(TargetSystem)) == ERROR)
  680.     {
  681.     /* search secondary list now */
  682.     if (Domain != NULL && strLen(Domain) != 0)
  683.     sPrintf(work, "%s _ %s", TargetSystem, Domain);
  684.     else
  685.     strCpy(work, TargetSystem);
  686.     if (!SystemInSecondary(work, TheDomain, &dup) || dup)
  687.       {
  688.       strCpy(System, TargetSystem);
  689.       strCpy(msgBuf.mbto, UserName);
  690.       if( logNetResults && netDebug)splitF(netLog, "Could not identify target '%s'.\n", TargetSystem);
  691.       netMailOut(TRUE, System, "unknown", FALSE, 0);
  692.       return ;
  693.  
  694.       }
  695.     Domain = TheDomain;
  696.     TargetSystem = work;
  697.  
  698.     }
  699.   else TargetSystem = netTemp.netName;
  700.   /* We know where, now to put it all together. */
  701.   strCpy(msgBuf.mbto, UserName);
  702.   if (!cfg.BoolFlags.RouteMail ||
  703.   (val == LOCALROUTE && !netBuf.nbflags.RouteFor))
  704.     {
  705.     sPrintf(msgBuf.mbtext, "System %s tried to illegally route via you.\n",
  706.     netBuf.netName);
  707.     netResult(msgBuf.mbtext);
  708.     return ;
  709.  
  710.     }
  711.   #ifdef WANTED
  712.   if (val == LOCALROUTE && !netTemp.nbflags.RouteTo)
  713.     {
  714.     sPrintf(msgBuf.mbtext, "System %s tried to route to %s.\n",
  715.     netBuf.netName, netTemp.netName);
  716.     netResult(msgBuf.mbtext);
  717.     return ;
  718.  
  719.     }
  720.   #endif
  721.   if (Domain != NULL)
  722.   netMailOut((Domain != NULL), TargetSystem, Domain, FALSE, Slot);
  723.   if (val == LOCALROUTE && thisNet == Slot)
  724.     {
  725.     /* kludge fix if system is routing back to itself */
  726.     netBuf.nbflags.HasRouted = netTemp.nbflags.HasRouted;
  727.     netBuf.nbHiRouteInd++;
  728.  
  729.     }
  730.  
  731.   }
  732. /*
  733. * IdStName()
  734. *
  735. * This function will find the STadel route name in our lists. It leaves
  736. * netTemp with the net element which matched, and returns the
  737. * slot number.  It does limited translations for underscores.
  738. */
  739. int IdStName(char *name)
  740.   {
  741.   int Slot;
  742.   char *Alias;
  743.   int StSearch(char *name);
  744.   while ((Alias = strchr(name, ' ')) != NULL)
  745.   *Alias = '_';
  746.   if ((Slot = StSearch(name)) != ERROR) return Slot;
  747.   if ((Alias = strchr(name, '_')) != NULL)
  748.     {
  749.     while ((Alias = strchr(name, '_')) != NULL)
  750.     *Alias = ' ';
  751.     Slot = StSearch(name);
  752.  
  753.     }
  754.   return Slot;
  755.  
  756.   }
  757. /*
  758. * StSearch()
  759. *
  760. * This function will search the ctdlnet for the given node by name.  If the
  761. * initial search fails, then the alias list is searched for an alias and
  762. * another attempt is made using the result.
  763. */
  764. int StSearch(char *name)
  765.   {
  766.   int Slot;
  767.   if ((Slot = searchNameNet(name, &netTemp)) != ERROR)
  768.   return Slot;
  769.   if ((Slot = searchNameNet(UseNetAlias(name, FALSE), &netTemp)) != ERROR)
  770.   return Slot;
  771.   return ERROR;
  772.  
  773.   }
  774. static label SearchResult;
  775. static char  *SearchTarget, GetAlias;
  776. /*
  777. * UseNetAlias()
  778. *
  779. * This will find a usenet alias or the converse from ALIASES.SYS.
  780. */
  781. char *UseNetAlias(char *Name, char FindAlias)
  782.   {
  783.   void *EatTrans();
  784.   SListBase Dummy =
  785.     {
  786.     NULL, NULL, NULL, NULL, EatTrans
  787.  
  788.     };
  789.   SYS_FILE fn;
  790.   char *c, *WorkName;
  791.   WorkName = strdup(Name);  /* use a work buffer */
  792.   SearchResult[0] = 0;
  793.   SearchTarget = WorkName;
  794.   if (!FindAlias) while ((c = strchr(WorkName, ' ')) != NULL) *c = '_';
  795.   makeSysName(fn, "aliases.sys", &cfg.roomArea);
  796.   GetAlias = FindAlias;
  797.   MakeList(&Dummy, fn, NULL); /* CHEAT!  WHEEEEEE! */
  798.   free(WorkName);
  799.   if (strLen(SearchResult) == 0) return Name;
  800.   if (FindAlias) while ((c = strchr(SearchResult, '_')) != NULL) *c = ' ';
  801.   return SearchResult;
  802.  
  803.   }
  804. /*
  805. * EatTrans()
  806. *
  807. * This digests a line of input from the ALIASES.SYS file, and, depending
  808. * on the value of the GetAlias variable, checks the variable SearchTarget
  809. * against either the alias or the name found on the input line.  If a
  810. * match is found the other field value is then copied into SearchResult,
  811. * a global variable.  Since this is only called from MakeList(), and we're
  812. * not really making a list, this always returns NULL.  We use MakeList()
  813. * just as a cheat.
  814. */
  815. void *EatTrans(char *line)
  816.   {
  817.   char *c;
  818.   NormStr(line);
  819.   if ((c = strchr(line, ' ')) != NULL)
  820.     {
  821.     *c = 0;
  822.     if (GetAlias)
  823.       {
  824.       /* check second field */
  825.       if (strCmpU(c + 1, SearchTarget) == SAMESTRING)
  826.         {
  827.         strCpy(SearchResult, line);
  828.  
  829.         }
  830.  
  831.       }
  832.     else
  833.       {
  834.       /* check first field */
  835.       if (strCmpU(line, SearchTarget) == SAMESTRING)
  836.         {
  837.         strCpy(SearchResult, c + 1);
  838.  
  839.         }
  840.  
  841.       }
  842.  
  843.     }
  844.   return NULL;
  845.  
  846.   }
  847. /*
  848. * ParseSTRoute()
  849. *
  850. * This parses a ST route path for recipient and target.  It can handle
  851. * domain specifications, too.
  852. *
  853. * RETURNS:
  854. *
  855. *  o FALSE if this does not appear to have any STadel routing information
  856. *    information in the field.
  857. *
  858. *  o TRUE if there did seem to be information and it was parsed out.
  859. *
  860. * str - the field containing the unparsed information.  This will be
  861. * changed by this function.
  862. *
  863. * TargetSystem - will contain the target system name after parsing.
  864. *
  865. * Domain - will contain the domain name after parsing.
  866. *
  867. * UserName - will contain the user's name after parsing.
  868. */
  869. static char ParseSTRoute(char *str, char **TargetSystem, char **Domain,
  870. char **UserName)
  871.   {
  872.   if ((*UserName = strrchr(str, '!')) == NULL)
  873.     {
  874.     return FALSE;
  875.  
  876.     }
  877.   **UserName = 0; /* now recipient's name does not interfere */
  878.   (*UserName)++;    /* with system target */
  879.   if ((*TargetSystem = strrchr(str, '!')) == NULL)
  880.   *TargetSystem = str;
  881.   else
  882.   (*TargetSystem)++;    /* gets us past our search target */
  883.   if ((*Domain = strrchr(str, '.')) != NULL)
  884.     {
  885.     **Domain = 0;
  886.     (*Domain)++;    /* with system target */
  887.  
  888.     }
  889.   return TRUE;
  890.  
  891.   }
  892.